import * as fs from 'fs-extra';
import * as path from 'path';
import matter from 'gray-matter';
import { StructuredSearchResult, FrontMatterData } from './types';
import { BriefingService } from './briefing-service';

export class StructuredSearchService {
  private briefingService: BriefingService;

  constructor() {
    this.briefingService = new BriefingService();
  }

  /**
   * 解析搜索词，支持中英文混合搜索
   * 对于中文，按字符分割；对于英文，按空格分割
   */
  private parseSearchTerms(keywords: string): string[] {
    const terms: string[] = [];
    const normalizedKeywords = keywords.toLowerCase().trim();
    
    // 按空格分割处理英文词汇和标点符号分隔的中文
    const spaceSeparated = normalizedKeywords.split(/\s+/).filter(term => term.length > 0);
    
    for (const term of spaceSeparated) {
      // 检测是否包含中文字符
      if (this.containsChinese(term)) {
        // 对于中文，进行更精细的分割
        // 保留完整的中文词汇，同时支持单字搜索
        terms.push(term); // 完整词汇
        
        // 如果词汇长度大于1，也添加单个字符用于部分匹配
        if (term.length > 1) {
          for (let i = 0; i < term.length; i++) {
            const char = term.charAt(i);
            if (this.isChinese(char) && !terms.includes(char)) {
              terms.push(char);
            }
          }
        }
      } else {
        // 英文词汇直接添加
        terms.push(term);
      }
    }
    
    return terms.filter(term => term.length > 0);
  }

  /**
   * 检测字符串是否包含中文字符
   */
  private containsChinese(text: string): boolean {
    return /[\u4e00-\u9fff]/.test(text);
  }

  /**
   * 检测单个字符是否为中文字符
   */
  private isChinese(char: string): boolean {
    return /[\u4e00-\u9fff]/.test(char);
  }

  /**
   * 改进的关键词匹配，支持中英文混合搜索
   */
  private matchesKeywords(frontMatter: FrontMatterData, searchTerms: string[]): boolean {
    // 将frontmatter转换为可搜索的文本
    const searchableText = this.flattenFrontMatter(frontMatter).toLowerCase();
    
    // 对于中文搜索，使用更宽松的匹配策略
    // 如果搜索词包含中文，只要有任意一个词匹配即可
    // 如果搜索词全为英文，则要求所有词都匹配
    const chineseTerms = searchTerms.filter(term => this.containsChinese(term));
    const englishTerms = searchTerms.filter(term => !this.containsChinese(term));
    
    let chineseMatch = chineseTerms.length === 0; // 如果没有中文词，默认匹配
    let englishMatch = englishTerms.length === 0; // 如果没有英文词，默认匹配
    
    // 中文词匹配：只要有任意一个词匹配即可
    if (chineseTerms.length > 0) {
      chineseMatch = chineseTerms.some(term => searchableText.includes(term));
    }
    
    // 英文词匹配：要求所有词都匹配
    if (englishTerms.length > 0) {
      englishMatch = englishTerms.every(term => searchableText.includes(term));
    }
    
    return chineseMatch && englishMatch;
  }
  async searchByMetadata(keywords: string, directoryPath?: string): Promise<StructuredSearchResult[]> {
    const results: StructuredSearchResult[] = [];
    const searchTerms = this.parseSearchTerms(keywords);
    const searchPath = directoryPath || process.cwd();
    
    try {
      // 查找所有markdown文件
      const markdownFiles = await this.findMarkdownFiles(searchPath);
      
      for (const filePath of markdownFiles) {
        try {
          const content = await fs.readFile(filePath, 'utf-8');
          const parsed = matter(content);
          
          // 检查frontmatter是否匹配搜索关键词
          if (this.matchesKeywords(parsed.data, searchTerms)) {
            const briefing = await this.briefingService.getBriefing(filePath);
            
            results.push({
              filePath,
              metadata: parsed.data,
              briefing,
            });
          }
        } catch (error) {
          console.error(`Error processing file ${filePath}:`, error);
        }
      }
    } catch (error) {
      console.error('Error in structured search:', error);
      throw error;
    }

    return results;
  }

  private flattenFrontMatter(obj: any, prefix: string = ''): string {
    let result = '';
    
    for (const [key, value] of Object.entries(obj)) {
      const currentKey = prefix ? `${prefix}.${key}` : key;
      
      if (value === null || value === undefined) {
        continue;
      }
      
      if (typeof value === 'object' && !Array.isArray(value)) {
        // 递归处理嵌套对象
        result += this.flattenFrontMatter(value, currentKey) + ' ';
      } else if (Array.isArray(value)) {
        // 处理数组
        result += `${currentKey}: ${value.join(' ')} `;
      } else {
        // 处理基本类型
        result += `${currentKey}: ${value} `;
      }
    }
    
    return result;
  }

  private async findMarkdownFiles(dirPath: string): Promise<string[]> {
    const files: string[] = [];
    
    try {
      const entries = await fs.readdir(dirPath, { withFileTypes: true });
      
      for (const entry of entries) {
        const fullPath = path.join(dirPath, entry.name);
        
        if (entry.isDirectory()) {
          // 跳过特定目录
          if (entry.name.startsWith('.') || entry.name === 'node_modules') {
            continue;
          }
          files.push(...await this.findMarkdownFiles(fullPath));
        } else if (entry.isFile() && entry.name.endsWith('.md')) {
          files.push(fullPath);
        }
      }
    } catch (error) {
      console.error(`Error reading directory ${dirPath}:`, error);
    }
    
    return files;
  }
  async searchBySpecificFields(fieldQueries: Record<string, string>, directoryPath?: string): Promise<StructuredSearchResult[]> {
    const results: StructuredSearchResult[] = [];
    const searchPath = directoryPath || process.cwd();
    
    try {
      const markdownFiles = await this.findMarkdownFiles(searchPath);
      
      for (const filePath of markdownFiles) {
        try {
          const content = await fs.readFile(filePath, 'utf-8');
          const parsed = matter(content);
          
          // 检查特定字段是否匹配
          if (this.matchesFieldQueries(parsed.data, fieldQueries)) {
            const briefing = await this.briefingService.getBriefing(filePath);
            
            results.push({
              filePath,
              metadata: parsed.data,
              briefing,
            });
          }
        } catch (error) {
          console.error(`Error processing file ${filePath}:`, error);
        }
      }
    } catch (error) {
      console.error('Error in field-specific search:', error);
      throw error;
    }

    return results;
  }
  private matchesFieldQueries(frontMatter: FrontMatterData, fieldQueries: Record<string, string>): boolean {
    for (const [field, query] of Object.entries(fieldQueries)) {
      const value = this.getNestedValue(frontMatter, field);
      if (!value) {
        return false;
      }
      
      const valueStr = Array.isArray(value) ? value.join(' ') : String(value);
      const queryTerms = this.parseSearchTerms(query);
      
      // 使用改进的匹配逻辑支持中文
      if (!this.matchesValueWithTerms(valueStr, queryTerms)) {
        return false;
      }
    }
    
    return true;
  }

  /**
   * 检查值是否匹配搜索词，支持中英文混合
   */
  private matchesValueWithTerms(value: string, searchTerms: string[]): boolean {
    const normalizedValue = value.toLowerCase();
    
    const chineseTerms = searchTerms.filter(term => this.containsChinese(term));
    const englishTerms = searchTerms.filter(term => !this.containsChinese(term));
    
    let chineseMatch = chineseTerms.length === 0;
    let englishMatch = englishTerms.length === 0;
    
    // 中文词匹配：只要有任意一个词匹配即可
    if (chineseTerms.length > 0) {
      chineseMatch = chineseTerms.some(term => normalizedValue.includes(term));
    }
    
    // 英文词匹配：要求所有词都匹配
    if (englishTerms.length > 0) {
      englishMatch = englishTerms.every(term => normalizedValue.includes(term));
    }
    
    return chineseMatch && englishMatch;
  }

  private getNestedValue(obj: any, path: string): any {
    const keys = path.split('.');
    let current = obj;
    
    for (const key of keys) {
      if (current && typeof current === 'object' && key in current) {
        current = current[key];
      } else {
        return null;
      }
    }
    
    return current;
  }
}
